import 'dart:async';

import 'package:distribution_mall_flutter/constant/constant.dart';
import 'package:distribution_mall_flutter/constant/point_constant.dart';
import 'package:distribution_mall_flutter/entity/user/user.dart';
import 'package:distribution_mall_flutter/generated/intl/messages_en.dart';
import 'package:distribution_mall_flutter/http/modules/user.dart';
import 'package:distribution_mall_flutter/provider/user/user_info.dart';
import 'package:distribution_mall_flutter/router/route_utils.dart';
import 'package:distribution_mall_flutter/utils/common_third.dart';
import 'package:distribution_mall_flutter/utils/firebase/firebase_analytics_utils.dart';
import 'package:distribution_mall_flutter/utils/log.dart';
import 'package:distribution_mall_flutter/router/router.dart';
import 'package:distribution_mall_flutter/router/router.gr.dart';
import 'package:distribution_mall_flutter/utils/storage.dart';
import 'package:distribution_mall_flutter/utils/utils.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';

import '../../pages/user/login/service/login_service.dart';

class ChangeLoginState extends StateNotifier<bool> {
  // 1登录，0未登录
  ChangeLoginState(super.state);

  void outLogin({bool go2login = true}) {
    state = false;
    EPstorage.outLogin();
    if (go2login &&
        (RouteUtils.routeStackList.isEmpty ||
            RouteUtils.routeStackList.last != RouteInfoEnum.login.routeName)) {
      appRouter.push(const LoginRoute());
    }
  }

  void login() {
    state = true;
  }
}

final loginStateProvider = StateNotifierProvider<ChangeLoginState, bool>(
    (ref) => ChangeLoginState(false));

class LoginState {
  int? tabIndex;
  String? account;
  String? pad;
  String code;
  GoogleSignIn? googleSignIn = kIsWeb
      ? null
      : GoogleSignIn(
          forceCodeForRefreshToken: true,
          scopes: [
            'email',
            // 'https://www.googleapis.com/auth/contacts.readonly',
          ],
        );
  bool showError;
  AutoCodeEntity? codeInfo;
  bool loginLoading;
  Map<String, dynamic> params;
  Timer? _time;
  int downTime;

  late PageController controller = PageController();
  LoginState({
    this.tabIndex,
    this.account,
    this.pad,
    this.code = '',
    this.codeInfo,
    this.showError = false,
    this.loginLoading = false,
    this.params = const {},
    this.downTime = 0,
  });

  LoginState.initial()
      : tabIndex = 0,
        account = '',
        pad = '',
        code = '',
        showError = false,
        downTime = 0,
        loginLoading = false,
        params = const {};

  LoginState copyWith(
          {int? tabIndex,
          String? account,
          String? pad,
          String? code,
          bool? showError,
          AutoCodeEntity? codeInfo,
          bool? loginLoading,
          Map<String, dynamic>? params,
          int? downTime}) =>
      LoginState(
        tabIndex: tabIndex ?? this.tabIndex,
        account: account ?? this.account,
        pad: pad ?? this.pad,
        code: code ?? this.code,
        showError: showError ?? this.showError,
        codeInfo: codeInfo ?? this.codeInfo,
        loginLoading: loginLoading ?? this.loginLoading,
        params: params ?? this.params,
        downTime: downTime ?? this.downTime,
      );

  String get formatPhone {
    if (account == null || account!.isEmpty) return '';
    return '${account!.substring(0, 3)} ${account!.substring(3, 6)} ${account!.substring(6, 9)}  ${account!.substring(9)}';
  }
}

final loginProvider =
    StateNotifierProvider.autoDispose<LoginViewModel, LoginState>((ref) {
  return LoginViewModel(
      loginCallbak: (int i) {
        if (i == 1) {
          ref.read(loginStateProvider.notifier).login();
          return;
        }
        ref.read(loginStateProvider.notifier).outLogin();
      },
      ref: ref);
});

class LoginViewModel extends StateNotifier<LoginState> {
  Timer? _time;
  final Function(int i) loginCallbak;
  LoginViewModel(
      {required this.loginCallbak, required AutoDisposeRef<Object?> ref})
      : super(LoginState.initial()) {
    ref.onDispose(() {
      endTime();
    });
  }

  void changeTabIndex(int index) {
    if (index == state.tabIndex) return;
    state.controller.animateToPage(index,
        duration: const Duration(milliseconds: 400), curve: Curves.easeInOut);
    state = state.copyWith(tabIndex: index);
  }

  void commonLogin(WidgetRef ref, String source, String token,
      {String email = '', int accountType = 2}) async {
    fun([i = 0]) {
      FirebaseAnalyticsUtils.logLogin(
          loginMethod: ThirdParty.phone,
          parameters: {
            'account': email,
            'accountType': accountType, // 1 是手机，2是google
            'success': i,
          });
      FirebaseAnalyticsUtils.logEvent(
          name: PointConstant.loginSign,
          parameters: {
            'account': email,
            'accountType': accountType, // 1 是手机，2是google
            'success': i,
          });
    }

    EPLoading.showLoadig();
    UserApi.loginThirdParty({
      'source': source,
      'phoneSystemModel': Utils.getPlatform().toUpperCase(),
      'token': token,
      'isV2': true
    }).then((bool bol) async {
      if (!bol) {
        fun();
        return;
      }
      bool res = await UserApi.loginTenantAndEndPoint();
      if (!res) {
        fun();
        return;
      }
      fun(1);
      ref.watch(loginServiceProvider).checkInviteCode();

      loginCallbak(1);
    }).whenComplete(() {
      EPLoading.dis();
    });
  }

  void googleSignIn(WidgetRef ref) async {
    try {
      var res = await state.googleSignIn?.signIn();
      GoogleSignInAuthentication googleSignInAuthentication =
          await res!.authentication;
      final AuthCredential credential = GoogleAuthProvider.credential(
        accessToken: googleSignInAuthentication.accessToken,
        idToken: googleSignInAuthentication.idToken,
      );
      commonLogin(
          ref, ThirdParty.google, googleSignInAuthentication.idToken ?? '',
          email: '');
      // firebase登录
      await FirebaseAuth.instance.signInWithCredential(credential);
    } catch (e) {
      LogUtil.d(e);
      FirebaseAnalyticsUtils.logEvent(
          name: PointConstant.loginSign,
          parameters: {
            'account': '',
            'accountType': 2, // 1 是手机，2是google
            'success': 0,
            'messages': e.toString()
          });
      FirebaseAnalyticsUtils.logLogin(
          loginMethod: ThirdParty.phone,
          parameters: {
            'account': '',
            'accountType': 2, // 1 是手机，2是google
            'success': 0,
            'messages': e.toString()
          });
    }
  }

  void appleSignIn(WidgetRef ref) async {
    try {
      final credential = await SignInWithApple.getAppleIDCredential(scopes: [
        AppleIDAuthorizationScopes.email,
        AppleIDAuthorizationScopes.fullName,
      ]);
      commonLogin(ref, ThirdParty.apple, credential.identityToken ?? '',
          accountType: 3);
    } catch (e) {
      debugPrint('ios========== $e');
    }
  }

  setCode(String code) {
    if (state.code == code) return;
    state = state.copyWith(code: code);
  }

  setShowError(bool bol) {
    if (state.showError == bol) return;
    state = state.copyWith(showError: bol);
  }

  setAccount(String str) {
    state = state.copyWith(account: str);
  }

  Future<AutoCodeEntity?> getCode(Map<String, dynamic> map) async {
    try {
      AutoCodeEntity? data = await UserApi.dynamicSendConfirmationCode(map);
      if (data == null) return null;
      state = state.copyWith(codeInfo: data);
      return data;
    } catch (e) {
      return null;
    }
  }

  cancelLoading() {
    EPLoading.dis();
    state = state.copyWith(loginLoading: false);
  }

  Future<bool> autoLogin(Map<String, dynamic> map) async {
    EPLoading.showLoadig();
    state = state.copyWith(loginLoading: true);
    fun([i = 1]) {
      FirebaseAnalyticsUtils.logEvent(
          name: PointConstant.loginSign,
          parameters: {
            'account': map['receiver'],
            'accountType': 1, // 1 是手机，2是google
            'success': i,
          });
      FirebaseAnalyticsUtils.logLogin(
          loginMethod: ThirdParty.phone,
          parameters: {
            'account': map['receiver'],
            'accountType': 1, // 1 是手机，2是google
            'success': i,
          });
    }

    try {
      GenerateTokenEntity? data = await UserApi.generateToken(map);
      if (data == null) {
        cancelLoading();
        return false;
      }
      bool bol = await UserApi.loginOrCreateAccount({
        'accountType': ReceiverType.phoneNumber,
        'captchaToken': data.captchaToken,
        'accountName': map['receiver']
      });
      debugPrint('bol $bol');
      if (!bol) {
        cancelLoading();
        return false;
      }
      bool pointBol = await UserApi.loginTenantAndEndPoint();
      if (!pointBol) {
        cancelLoading();
        return false;
      }

      state = state.copyWith(loginLoading: false);
      loginCallbak(1);
      EPLoading.dis();
      fun(1);

      return true;
    } catch (e) {
      fun(0);
      cancelLoading();
      return false;
    }
  }

  setParams(Map<String, dynamic> map) {
    state = state.copyWith(params: map);
  }

  startTime(int downTime) {
    state = state.copyWith(downTime: downTime);
    if (_time != null) return;
    _time = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (state.downTime > 0) {
        state = state.copyWith(downTime: state.downTime - 1);
        if (state.downTime <= 0) {
          endTime();
        }
      }
    });
  }

  endTime() {
    if (_time != null) {
      _time!.cancel();
      state = state.copyWith(
        downTime: 0,
      );
      _time = null;
    }
  }
}
